#include "Customer.hh"
#include "Bank.hh"
#include "SavingsAccount.hh"
#include "CheckingAccount.hh"
#include "Utility.hh"
#include <iomanip>

Customer::Customer() : savingsAccount(nullptr), checkingAccount(nullptr), bank(nullptr) {}
Customer::Customer(const std::string& name, const std::string& savingsID, const std::string& checkingID, Bank* bank)
    : name(name){
    savingsAccount = new SavingsAccount(savingsID, 0.0, name, bank);
    checkingAccount = new CheckingAccount(checkingID, 0.0, name, bank);
    this->bank = bank;
}
Customer::~Customer() {
    delete savingsAccount;
    delete checkingAccount;
}
Customer::Customer(const Customer& other) : name(other.name), bank(other.bank) {
    savingsAccount = new SavingsAccount(*other.savingsAccount);
    checkingAccount = new CheckingAccount(*other.checkingAccount);
}
Customer& Customer::operator=(const Customer& other) {
    if (this != &other) {
        name = other.name;
        bank = other.bank;
        delete savingsAccount;
        delete checkingAccount;
        savingsAccount = new SavingsAccount(*other.savingsAccount);
        checkingAccount = new CheckingAccount(*other.checkingAccount);
    }
    return *this;
}

const std::string& Customer::getName() const {
    return name;
}

SavingsAccount* Customer::getSavingsAccount() const {
    return savingsAccount;
}

CheckingAccount* Customer::getCheckingAccount() const {
    return checkingAccount;
}

void Customer::accessAccounts() {
    while (true) {
        std::cout << "===== Customer: " << name << " =====\n";
        std::cout << "This customer has the following accounts:\n";

        std::cout << "1. Savings Account: " << savingsAccount->getAccountID() 
                  << " |  Balance: $" << std::fixed << std::setprecision(2) << savingsAccount->getBalance() << "\n";
        std::cout << "2. Checking Account: " << checkingAccount->getAccountID() 
                  << " |  Balance: $" << std::fixed << std::setprecision(2) << checkingAccount->getBalance() << "\n";

        std::cout << "\nOptions:\n";
        std::cout << "1. Access Savings Account\n";
        std::cout << "2. Access Checking Account\n";
        std::cout << "3. View all transactions for this customer\n";
        std::cout << "4. Generate customer report\n";
        std::cout << "5. Return to main menu\n";
        std::cout << "Please choose: ";

        int choice;
        std::cin >> choice;

        switch (choice) {
            case 1: {
                savingsAccount->accessAccount();
                break;
            }
            case 2: {
                checkingAccount->accessAccount();
                break;
            }
            case 3: {
                for (const Transaction& transaction : savingsAccount->getTransactions()) {
                    transaction.print();
                }
                for (const Transaction& transaction : checkingAccount->getTransactions()) {
                    transaction.print();
                }
                if (savingsAccount->getTransactions().empty() && checkingAccount->getTransactions().empty()) {
                    std::cout << "No transactions found for this customer.\n";
                } else {
                    std::cout << "Press Enter to continue...\n";
                }
                std::cin.ignore();
                std::cin.get();
                break;
            }
            case 4: {
                bank->generateCustomerReport(name);
                break;
            }
            case 5: {
                return;
            }
            default: {
                std::cout << "Invalid choice. Please try again.\n";
            }
        }
    }
}